<template>
  <div class="home-container">
    <!-- //临时测试按钮
    <button @click="test">测试</button> -->
    <!-- 搜索栏：固定在顶部，通过showSearchBar状态控制显示和隐藏 -->
    <!-- 使用CSS的transform属性和transition实现平滑的上下滑动效果 -->
    <div class="search-bar" :class="{ 'search-bar-hidden': !showSearchBar }">
      <div class="search-container">
        <Icon name="search" class="search-icon" />
        <input 
          type="text" 
          placeholder="搜索内容、用户或话题" 
          class="search-input"
          v-model="searchKeyword"
          @keyup.enter="handleSearch"
        />
      </div>
    </div>

    <!-- 分类选项卡：固定在搜索栏下方，搜索栏隐藏时会上移到顶部 -->
    <!-- 通过tabs-top-hidden类控制位置变化，实现与搜索栏的联动效果 -->
    <div class="category-tabs" :class="{ 'tabs-top-hidden': !showSearchBar }">
      <div class="tabs-wrapper">
        <button 
          v-for="category in categories" 
          :key="category.id" 
          :class="['tab-btn', { active: activeCategory === category.id }]"
          @click="handleCategoryClick(category.id)"
        >
          {{ category.name }}
        </button>
      </div>
      
      <!-- 分类下拉菜单：点击"分类"标签时显示 -->
      <!-- 使用绝对定位(position: absolute)实现下拉效果，z-index设置确保显示层级 -->
      <div v-if="showCategoryList" class="category-dropdown">
        <div class="category-list">
          <div 
            v-for="category in categoryList" 
            :key="category.id"
            :class="['category-item', { active: selectedSubCategory === category.id }]"
            @click="handleSubCategoryClick(category.id)"
          >
            {{ category.name }}
          </div>
        </div>
      </div>
    </div>

    <!-- 内容区域：可滚动区域，包含瀑布流布局 -->
    <!-- 通过@scroll绑定滚动事件，用于检测滑动加载数据和控制搜索栏显隐 -->
    <main class="content-area" ref="contentRef" @scroll="handleScroll">
      <van-pull-refresh v-model="state.isRefresh" @refresh="onRefresh">
      <!-- 瀑布流布局实现：通过flex布局将内容分为多列 -->
      <!-- 使用CSS变量(--column-count)动态控制列数，实现响应式布局 -->
      <div class="waterfall-layout" :style="{ '--column-count': columnCount }">
        <!-- 动态生成列：根据columnCount的值生成对应数量的列容器 -->





        <!-- 1.
   - 使用 `v-for` 指令遍历 `postColumns` 数组，`postColumns` 数组存储了按列分割后的帖子数据。
   - `(column, index)` 表示遍历过程中获取每一列的数据 `column` 以及对应的索引 `index`。
   - `:key="index"` 为每个列元素指定一个唯一的 `key`，帮助 Vue 高效地更新 DOM。
   - `class="waterfall-column"` 为列元素添加样式类，用于控制列的布局。 -->
        <div v-for="(column, index) in postColumns" :key="index" class="waterfall-column">
          
   <!-- - 在每一列内部，使用 `v-for` 指令遍历该列中的帖子数据 `column`。
   - `post` 表示遍历过程中获取的单个帖子数据。
   - `:key="post.id"` 为每个帖子卡片指定一个唯一的 `key`，使用帖子的 `id` 确保唯一性。
   - `class="post-card"` 为帖子卡片元素添加样式类，用于控制帖子卡片的样式。 -->
          <!-- 帖子卡片 -->
          <div v-for="post in column" :key="post.entryId" class="post-card" @click="handlePostClick(post)">
            <!-- 用户信息 -->
            <div class="user-info">
              <img :src="post.publisher.avatar" alt="用户头像" class="avatar" />
              <span class="username">{{ post.publisher.username }}</span>
            </div>

            <!-- 帖子内容 -->
            <div class="post-content">
              <!-- 无图片帖子只显示标题 -->
              <h3 v-if="!post.entriesPic" class="post-title-only">{{ post.entryName }}</h3>
              
              <!-- 有图片帖子 -->
              <div v-else>
                <!-- 帖子图片 - 动态高度 --> <!-- 此处 height 用于设定帖子图片的高度为 90 像素 -->
                <div class="post-image-container">
                  <img 
                    :src="post.entriesPic" 
                    alt="帖子图片" 
                    class="post-image" 
                   
                   
                  />
                </div>
                <!-- 帖子标题 -->
                <h3 class="post-title">{{ post.entryName }}</h3>
              </div>
            </div>

            <!-- 帖子互动数据 -->
            <div class="post-stats">
              <div class="stat-item">
                <Icon name="like-o" /> 
                <span>{{ post.likes }}</span>
              </div>
              <div class="stat-item">
                <Icon name="star-o" /> 
                <span>{{ post.collects }}</span>
              </div>
            </div>
          </div>
        </div>
      </div>
      
      <!-- 加载更多指示器 -->
      <div v-if="state.isLoading" class="loading-indicator">
        <Loading type="spinner" />加载中...
      </div>
      </van-pull-refresh>
    </main>

    <!-- 底部导航栏已移至tab-bar组件 -->
  </div>
  <tabbar/>
</template>

<script setup lang="ts">
import tabbar from '@/components/tab-bar.vue'
// 导入Vue相关功能和Vant组件
import { ref, onMounted, computed, watch, onBeforeUnmount, reactive } from 'vue';
import { useRouter } from 'vue-router';
import { Icon, Loading,PullRefresh } from 'vant';
import axios from '../utils/axios';

const router = useRouter();

const entriesList = ref([]); // 帖子列表数据（推荐）
const entriesListHot = ref([]); // 帖子列表数据（热门）
const entriesListCategory = ref([]); // 帖子列表数据（分类）


let state =reactive({
  isRefresh:false,
  isLoading:false,
  finished:false,
  count:1,
})
const data = reactive({
    page:1,
    limit:10,
})



const init=()=>{
  console.log('开始请求数据，页码:', data.page);
  console.log('请求参数:', { page: data.page, limit: data.limit });
  
  axios.post("/api/entries/listWithUser",{
    page:data.page,
    limit:data.limit,
  })
    .then(res=>{
      console.log('后端返回数据:', res);
      // 修复数据处理逻辑 - 根据实际返回格式调整
      // 从日志看数据直接在res对象中，records是包含10条数据的数组
      if (res && res.records && res.records.length > 0) {
        console.log('获取到的帖子数量:', res.records.length);
        entriesList.value = entriesList.value.concat(res.records);
        console.log('entriesList更新后的长度:', entriesList.value.length);
        // 请求成功后递增页码
        data.page++;
      } else {
        // 没有数据了，设置finished为true
        console.log('没有更多数据了', res);
        state.finished = true;
      }
      state.isLoading = false;
      // 如果是刷新操作，请求完成后设置isRefresh为false
      if (state.isRefresh) {
        state.isRefresh = false;
      }
    })
    .catch(err => {
      console.error('加载帖子列表失败:', err);
      console.log('错误详情:', err.message, err.response);
      state.isLoading = false;
      // 如果是刷新操作，即使失败也要设置isRefresh为false
      if (state.isRefresh) {
        state.isRefresh = false;
      }
    })
    .finally(() => {
      console.log("请求完成 - entriesList长度:"+entriesList.value.length);
    })
}

// 组件挂载时的初始化操作：
// 1. 恢复用户上次浏览状态（分类、子分类选择）
// 2. 根据恢复的状态加载相应数据
// 3. 设置响应式布局和事件监听
onMounted(() => {
  // 状态恢复与数据加载的优先级逻辑：
  // 1. 优先检查是否有保存的子分类状态
  if (selectedSubCategory.value) {
    // 子分类状态存在：设置分类按钮为激活状态
    activeCategory.value = '1';
    // 确保分类列表已加载
    if (categoryList.value.length === 0) {
      fetchCategories();
    }
    // 加载子分类对应的数据（非加载更多模式）
    fetchPostsByCategory(selectedSubCategory.value, false);
  } 
  // 2. 如果没有子分类状态，检查是否是热门分类
  else if (activeCategory.value === '3') {
    // 热门分类：重置参数并加载热门数据
    data.page = 1;
    state.finished = false;
    entriesListHot.value = [];
    fetchHotEntries();
  } else {
    // 3. 默认加载推荐数据
    init();
  }
  
  // 响应式布局设置：
  // 1. 初始化瀑布流列数
  updateColumnCount();
  // 2. 监听窗口大小变化，动态调整瀑布流列数
  window.addEventListener('resize', updateColumnCount);
})


const onRefresh = () => {
  console.log("Refresh count:", state.count, "--", state.finished);
  state.isRefresh = true;
  state.count = 1;
  state.finished = false;
  data.page = 1;
  
  if (activeCategory.value === '3') {
    entriesListHot.value = [];
    fetchHotEntries();
  } else {
    entriesList.value = [];
    init();
  }
};



// 响应式数据定义


// 从本地存储获取保存的分类状态，如果没有则使用默认值
const savedCategory = localStorage.getItem('activeCategory');
const activeCategory = ref(savedCategory || '2'); // 当前激活的分类ID - 修改为推荐
const contentRef = ref(null); // 内容区域的DOM引用
const columnCount = ref(2); // 默认两列
const postColumns = ref([]); // 用于存储分割后的帖子列数据

// 分类选项数据 - 修改为分类、推荐、热门
const categories = [
  { id: '1', name: '分类' },
  { id: '2', name: '推荐' },
  { id: '3', name: '热门' }
];

// 搜索相关数据
const searchKeyword = ref('');
const showSearchBar = ref(true);
const lastScrollTop = ref(0);

// 处理搜索事件
const handleSearch = () => {
  if (searchKeyword.value.trim()) {
    router.push({
      path: '/search',
      query: {
        keyword: searchKeyword.value.trim()
      }
    });
  }
};

// 新增状态管理
const showCategoryList = ref(false); // 是否显示分类列表
const categoryList = ref([]); // 获取的分类列表
// 从本地存储获取保存的子分类状态
const savedSubCategory = localStorage.getItem('selectedSubCategory') || '';
const selectedSubCategory = ref<string>(savedSubCategory); // 选中的子分类

/**
 * 响应式调整列数：根据屏幕宽度动态计算瀑布流的列数
 * 小屏幕(手机)显示1列，中等屏幕(平板)显示2列，大屏幕(电脑)显示3列或4列
 * 调整后会自动触发watch重新排列帖子
 */
const updateColumnCount = () => {
  const width = window.innerWidth;
  if (width <= 375) {
    columnCount.value = 1;
  } else if (width <= 768) {
    columnCount.value = 2;
  } else if (width <= 1024) {
    columnCount.value = 3;
  } else {
    columnCount.value = 4;
  }
};

// 这段代码的作用是监听 `posts` 和 `columnCount` 的变化，当它们发生变化时，将 `posts` 数组中的帖子数据重新分配到不同的列中，以实现瀑布流布局。具体解释如下：
// 1. 使用 `watch` 函数监听 `posts` 和 `columnCount` 这两个响应式变量。
// 2. 当 `posts` 或 `columnCount` 发生变化时，执行回调函数。
// 3. 在回调函数中，首先根据 `columnCount` 的值初始化一个空的列数组 `postColumns`。
// 4. 然后遍历 `posts` 数组，通过取模运算将每个帖子分配到对应的列中。
// 5. `{ immediate: true }` 表示在 `watch` 初始化时立即执行一次回调函数。

// 以下是代码本身：
// 清理数据中的URL格式问题
const cleanPostData = (post) => {
  // 深拷贝帖子对象，避免直接修改原数据
  const cleanedPost = { ...post };
  
  // 清理entriesPic字段中的反引号和空格
  if (cleanedPost.entriesPic && typeof cleanedPost.entriesPic === 'string') {
    cleanedPost.entriesPic = cleanedPost.entriesPic.trim().replace(/`/g, '');
  }
  
  // 清理publisher.avatar字段中的反引号和空格
  if (cleanedPost.publisher && cleanedPost.publisher.avatar && typeof cleanedPost.publisher.avatar === 'string') {
    cleanedPost.publisher.avatar = cleanedPost.publisher.avatar.trim().replace(/`/g, '');
  }
  
  return cleanedPost;
};

// 瀑布流核心实现：通过watch监听数据变化并动态分配帖子到各列
// 1. 监听多个响应式数据：帖子列表、列数、分类状态等
// 2. 当任何相关数据变化时，重新计算瀑布流布局
// 3. immediate: true确保组件加载时立即执行一次
watch([entriesList, entriesListHot, entriesListCategory, columnCount, activeCategory, selectedSubCategory], () => {
  // 初始化空列数组，数量等于当前设置的列数
  postColumns.value = Array.from({ length: columnCount.value }, () => []);
  
  
  // 数据选择逻辑：根据当前分类状态选择正确的数据源
  // 优先级：子分类 > 热门分类 > 推荐分类
  let currentData = [];
  
  if (selectedSubCategory.value) {
    // 如果选择了子分类，使用分类数据
    currentData = entriesListCategory.value;
  } else if (activeCategory.value === '3') {
    // 如果激活的是热门分类，使用热门数据
    currentData = entriesListHot.value;
  } else {
    // 默认使用推荐数据
    currentData = entriesList.value;
  }
  
  // 数据分配算法：使用取模运算将帖子交替分配到不同列
  // 这种方式确保各列帖子数量相对均衡，实现瀑布流效果
  currentData.forEach((post, index) => {
    // 清理数据中的格式问题（如反引号和空格）
    const cleanedPost = cleanPostData(post);
    // 通过取模计算当前帖子应该放入哪一列
    const columnIndex = index % columnCount.value;
    // 将帖子添加到对应列中
    postColumns.value[columnIndex].push(cleanedPost);
  });
}, { immediate: true });






/**
 * 处理滚动加载更多和搜索栏显示/隐藏
 * 当用户滚动到页面底部时，自动加载下一页数据
 * 当用户向下滚动时隐藏搜索栏，向上滚动时显示搜索栏
 */
// 这段代码定义了 `handleScroll` 函数，用于处理页面滚动事件。具体逻辑如下：
// 1. 首先检查 `contentRef` 是否存在，以及 `loading` 状态是否为真。如果 `contentRef` 不存在或者正在加载数据，则直接返回，不执行后续逻辑。
// 2. 从 `contentRef` 获取 `scrollTop`（滚动条垂直位置）、`scrollHeight`（内容总高度）和 `clientHeight`（可视区域高度）。
// 3. 判断是否滚动到了页面底部附近（当 `scrollTop` 加上 `clientHeight` 大于等于 `scrollHeight` 减去 100 时），如果是，则触发加载更多数据的操作。
// 4. 简单计算下一页页码（通过帖子数量除以 10 取整后加 1），并调用 `fetchPosts` 函数获取下一页数据。

// 以下是代码本身：
// 处理滚动事件：实现两个核心功能
// 1. 上拉加载更多数据：检测滚动到底部附近时触发数据加载
// 2. 搜索栏智能显隐：根据滚动方向控制搜索栏的显示和隐藏
const handleScroll = () => {
  // 边界条件检查：确保内容容器存在，且不在加载中或已完成状态
  if (!contentRef.value || state.isLoading || state.finished) return;
  
  const { scrollTop, scrollHeight, clientHeight } = contentRef.value;
  
  // 滑动加载数据检测机制：
  // 当滚动到距离底部100px以内时触发加载
  if (scrollTop + clientHeight >= scrollHeight - 100) {
    state.isLoading = true;
    // 根据当前分类状态选择对应的加载函数
    if (selectedSubCategory.value) {
      // 子分类模式：加载更多分类数据
      fetchPostsByCategory(selectedSubCategory.value, true);
    } else if (activeCategory.value === '3') {
      // 热门模式：加载更多热门数据
      fetchHotEntries();
    } else {
      // 推荐模式：加载更多推荐数据
      init();
    }
  }
  
  // 向上滑动隐藏搜索栏的实现逻辑：
  // 1. 设置滚动阈值(50px)避免微小滚动触发状态变化
  // 2. 记录上次滚动位置，通过比较判断滚动方向
  // 3. 向下滚动超过阈值时隐藏搜索栏，向上滚动时显示搜索栏
  const scrollThreshold = 50; // 滚动阈值
  if (scrollTop > lastScrollTop.value && scrollTop > scrollThreshold) {
    // 向下滚动超过阈值，隐藏搜索栏（提升可视区域）
    showSearchBar.value = false;
  } else if (scrollTop < lastScrollTop.value) {
    // 向上滚动，显示搜索栏（方便用户搜索）
    showSearchBar.value = true;
  }
  
  // 更新上次滚动位置
  lastScrollTop.value = scrollTop;
};

/**
 * 暂时手动设定分类列表
 */
const fetchCategories = async () => {
 
    const mockCategories = [
      { id: '1', name: '直播' },
      { id: '2', name: '游戏' },
      { id: '3', name: '影视' },
      { id: '4', name: '动漫' },
      { id: '5', name: '抖音' },
      { id: '6', name: '贴吧' },
      { id: '7', name: 'B站' },
      { id: '8', name: '其他' },
    ];
    categoryList.value = mockCategories;
  
};

/**
 * 分类栏实现：处理顶部导航栏中分类按钮的点击事件
 * @param categoryId 分类ID - 1:分类, 2:推荐, 3:热门
 * 
 * 顶部导航栏实现逻辑：
 * 1. 包含三个核心分类：分类、推荐、热门
 * 2. 点击不同按钮会切换不同的内容区域和数据加载逻辑
 * 3. 使用activeCategory状态跟踪当前激活的分类，并保存到本地存储实现状态保持
 * 4. 点击分类按钮时会显示/隐藏下拉分类列表
 */
const handleCategoryClick = (categoryId: string) => {
  if (categoryId === '1') {
    // 点击"分类"时：切换分类下拉列表的显示状态
    showCategoryList.value = !showCategoryList.value;
    if (showCategoryList.value) {
      selectedSubCategory.value = '';
      // 如果分类列表为空，加载分类数据
      if (categoryList.value.length === 0) {
        fetchCategories();
      }
    }
    // 更新当前激活分类并保存到本地存储
    activeCategory.value = categoryId;
    localStorage.setItem('activeCategory', categoryId);
  } else if (categoryId === '2') {
    // 点击"推荐"时：隐藏分类列表，切换到推荐模式
    showCategoryList.value = false;
    activeCategory.value = categoryId;
    localStorage.setItem('activeCategory', categoryId);
    // 清空选中的子分类
    selectedSubCategory.value = '';
    localStorage.setItem('selectedSubCategory', '');
    // 重置页码和状态
    data.page = 1;
    state.finished = false;
    // 清空列表并重新加载推荐数据
    entriesList.value = [];
    init();
  } else if (categoryId === '3') {
    // 点击"热门"时：隐藏分类列表，切换到热门模式
    showCategoryList.value = false;
    activeCategory.value = categoryId;
    localStorage.setItem('activeCategory', categoryId);
    // 清空选中的子分类
    selectedSubCategory.value = '';
    localStorage.setItem('selectedSubCategory', '');
    // 重置页码和状态
    data.page = 1;
    state.finished = false;
    // 清空热门列表
    entriesListHot.value = [];
    // 调用获取热门数据的函数
    fetchHotEntries();
  }
};

const fetchHotEntries = () => {
  console.log('开始请求热门数据，页码:', data.page);
  state.isLoading = true;
  
  axios.post("/api/entries/hotList", {
    page: data.page,
    limit: data.limit,
  })
    .then(res => {
      console.log('后端返回热门数据:', res);
      if (res && res.records && res.records.length > 0) {
        entriesListHot.value = entriesListHot.value.concat(res.records);
        data.page++;
      } else {
        state.finished = true;
      }
      state.isLoading = false;
      // 如果是刷新操作，请求完成后设置isRefresh为false
      if (state.isRefresh) {
        state.isRefresh = false;
      }
    })
    .catch(err => {
      console.error('加载热门帖子列表失败:', err);
      state.isLoading = false;
      // 如果是刷新操作，即使失败也要设置isRefresh为false
      if (state.isRefresh) {
        state.isRefresh = false;
      }
    })
};


/**
 * 处理子分类点击事件
 * @param subCategoryId 子分类ID
 */
const handleSubCategoryClick = (subCategoryId: string) => {
  selectedSubCategory.value = subCategoryId;
  showCategoryList.value = false;
  
  // 设置activeCategory为分类，确保选中状态显示在分类按钮上
  activeCategory.value = '1';
  // 保存分类状态到本地存储
  localStorage.setItem('activeCategory', '1');
  // 保存子分类状态到本地存储
  localStorage.setItem('selectedSubCategory', subCategoryId);
  
  // 根据子分类获取对应的帖子，首次加载模式
  fetchPostsByCategory(subCategoryId, false);

};

// 添加isLoadMore参数来区分首次加载和滚动加载
const fetchPostsByCategory = (categoryId: string, isLoadMore: boolean = false) => {
  console.log('开始请求分类数据，分类ID:', categoryId, '是否加载更多:', isLoadMore);
  state.isLoading = true;
  
  // 只有在非加载更多模式下才重置页面和完成状态
  if (!isLoadMore) {
    data.page = 1;
    state.finished = false;
  }
  
  axios.post("/api/entries/searchFirstCategory", {
    categoryId: categoryId,
    page: data.page,
    limit: data.limit,
  })
    .then(res => {
      console.log('后端返回分类数据:', res);
      
      // 关键修复：处理分类数据的特殊结构
      let records = [];
      // 检查返回数据是否直接是数组（分类数据的情况）
      if (Array.isArray(res)) {
        records = res;
      } 
      // 或者检查是否有records字段（推荐数据的结构）
      else if (res && res.records && Array.isArray(res.records)) {
        records = res.records;
      }
      
      if (records && records.length > 0) {
        // 根据是否加载更多来决定是替换还是追加数据
        if (isLoadMore && entriesListCategory.value.length > 0) {
          entriesListCategory.value = [...entriesListCategory.value, ...records];
        } else {
          entriesListCategory.value = [...records];
        }
        console.log('分类数据更新成功，记录数:', entriesListCategory.value.length);
        data.page++;
      } else {
        console.log('没有获取到分类数据');
        // 如果是首次加载且没有数据，清空列表
        if (!isLoadMore) {
          entriesListCategory.value = [];
        }
        state.finished = true;
      }
      state.isLoading = false;
      // 如果是刷新操作，请求完成后设置isRefresh为false
      if (state.isRefresh) {
        state.isRefresh = false;
      }
    })
    .catch(err => {
      console.error('加载分类帖子列表失败:', err);
      // 如果是首次加载且失败，清空列表
      if (!isLoadMore) {
        entriesListCategory.value = [];
      }
      state.isLoading = false;
      // 如果是刷新操作，即使失败也要设置isRefresh为false
      if (state.isRefresh) {
        state.isRefresh = false;
      }
    })
}

/**
 * 监听分类变化，切换分类时重新获取数据
 */
watch(activeCategory, (newCategory) => {
  if (newCategory !== '1') {
    // 如果不是"分类"，则正常获取数据
   
  }
});

// 组件挂载时获取初始数据并监听窗口大小变化
// 此代码在组件挂载时执行以下操作：
// 1. 调用 fetchPosts 函数获取帖子数据

// onMounted(() => {
//   fetchPosts();
//   updateColumnCount();
//   window.addEventListener('resize', updateColumnCount);
// });

// 组件卸载前移除事件监听
onBeforeUnmount(() => {
  window.removeEventListener('resize', updateColumnCount);
});

/**
 * 处理帖子点击事件
 * @param post 帖子数据
 */
const handlePostClick = (post) => {
  // 通过路由query传递完整的帖子数据，避免再次请求
  router.push({
    name: 'entry',
    query: {
      entryData: JSON.stringify(post)
    }
  });
};

// const test = () => {
//   router.push({
//     name: 'entryWithId',
//     params: { entryId: '33' }
//   });
// }
</script>

<style scoped>
/* 全局重置（注意：这部分通常放在全局样式文件中，但为完整性在此包含） */
html, body {
  margin: 0;
  padding: 0;
  width: 100%;
  height: 100%;
  overflow-x: hidden;
}

/* 整体容器样式 */
.home-container {
  display: flex;
  flex-direction: column;
  height: 100vh;
  width: 100%;
  margin: 0;
  padding: 0;
  padding-bottom: 60px;
  box-sizing: border-box;
  background-color: #f8f8f8;
}

/* 搜索栏 CSS 实现：
   1. 使用 fixed 定位固定在页面顶部
   2. 设置高 z-index 确保显示在最上层
   3. 添加 transition 实现平滑的显示/隐藏动画
   4. 通过 .search-bar-hidden 类控制隐藏状态 */
.search-bar {
  position: fixed;     /* 固定在页面顶部 */
  top: 0;
  background-color: white;
  z-index: 100;        /* 确保显示在所有内容上层 */
  padding: 12px 16px;
  border-bottom: 1px solid #f0f0f0;
  transition: transform 0.3s ease; /* 0.3秒平滑过渡动画，实现搜索栏的优雅显示/隐藏 */
  width: 100%;
  box-sizing: border-box;
}

/* 向上滑动隐藏搜索栏的CSS实现：
   通过 transform: translateY(-100%) 将搜索栏移出屏幕顶部
   结合JS的滚动事件监听动态添加/移除此类
   这种方式比display:none有更好的视觉体验 */
.search-bar-hidden {
  transform: translateY(-100%); /* 将搜索栏向上移动，完全移出屏幕 */
}

.search-container {
  display: flex;
  align-items: center;
  background-color: #f5f5f5;
  border-radius: 20px;
  padding: 8px 16px;
  height: 40px;
  box-sizing: border-box;
  max-width: 500px;
  margin: 0 auto;
}

.search-icon {
  font-size: 18px;
  color: #999;
  margin-right: 8px;
}

.search-input {
  flex: 1;
  border: none;
  background: none;
  outline: none;
  font-size: 14px;
  color: #333;
  height: 100%;
}

.search-input::placeholder {
  color: #999;
}

.scan-icon {
  font-size: 20px;
  color: #666;
  margin-left: 8px;
}

/* 分类栏/顶部导航栏 CSS 实现：
   1. 使用 fixed 定位固定在搜索栏下方
   2. 设置 z-index 确保显示在内容区之上，但在搜索栏之下
   3. 添加 transition 实现与搜索栏的联动效果
   4. 通过 .tabs-top-hidden 类控制搜索栏隐藏时上移 */
.category-tabs {
  position: fixed;
  top: 60px; /* 初始位置，在搜索栏下方（搜索栏高度约60px） */
  left: 0;
  right: 0;
  background-color: white;
  z-index: 90;        /* 低于搜索栏的z-index，形成层级关系 */
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
  transition: top 0.3s ease; /* 与搜索栏同步的过渡动画，实现无缝联动 */
  width: 100%;
}

/* 分类选项卡上移状态：当搜索栏隐藏时，分类选项卡上移到屏幕顶部
   保持界面的连续性和可用性 */
.tabs-top-hidden {
  top: 0; /* 搜索栏隐藏时，移动到顶部位置 */
}

.tabs-wrapper {
  display: flex;
  justify-content: space-around; /* 平均分布三个栏目 */
  padding: 10px 0;
  overflow-x: hidden;
  width: 100%;
  box-sizing: border-box;
}

.tabs-wrapper::-webkit-scrollbar {
  display: none;
}

.tab-btn {
  padding: 8px 0;
  background: none;
  border: none;
  border-radius: 0;
  font-size: 16px;
  font-weight: 500;
  cursor: pointer;
  color: #666;
  flex: 1;
  text-align: center;
  position: relative;
}

.tab-btn.active {
  color: #ff2442;
  font-weight: 600;
}

.tab-btn.active::after {
  content: '';
  position: absolute;
  bottom: 0;
  left: 50%;
  transform: translateX(-50%);
  width: 20px;
  height: 3px;
  background-color: #ff2442;
  border-radius: 2px;
}

/* 分类下拉菜单 */
.category-dropdown {
  position: absolute;
  top: 100%;
  left: 0;
  right: 0;
  background-color: white;
  border-top: 1px solid #f0f0f0;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
  z-index: 95;
  max-height: 300px;
  overflow-y: auto;
}

.category-list {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 8px;
  padding: 16px;
}

.category-item {
  padding: 12px 8px;
  text-align: center;
  background-color: #f8f8f8;
  border-radius: 8px;
  font-size: 14px;
  cursor: pointer;
  transition: all 0.2s ease;
  border: 1px solid transparent;
}

.category-item:hover {
  background-color: #ff2442;
  color: white;
  transform: translateY(-2px);
}

.category-item.active {
  background-color: #ff2442;
  color: white;
  border-color: #ff2442;
}

/* 主内容区域 */
.content-area {
  flex: 1;
  width: 100%;
  margin: 0;
  padding: 0 0 10px;
  box-sizing: border-box;
  padding-top: 110px; /* 固定顶部间距，避免动态计算问题 */
  overflow-y: auto;
}

/* 瀑布流布局 CSS 核心实现：
   1. 使用 flex 布局创建水平排列的容器
   2. 结合 CSS 变量和 calc() 函数实现动态列宽计算
   3. 通过间距控制实现列与列之间的分隔效果
   4. 响应式设计，在不同屏幕尺寸下自动调整布局 */
.waterfall-layout {
  display: flex;       /* 使用弹性布局创建多列 */
  justify-content: flex-start; /* 左对齐排列 */
  padding-top: 12px;
  width: 100%;
  box-sizing: border-box;
}

/* 瀑布流列容器：
   1. 使用 CSS 变量 --column-count 动态控制列宽
   2. 通过 calc() 计算每列的精确宽度，考虑列间距
   3. 计算公式：(总宽度 - 所有列间距) / 列数
   4. 确保在不同列数下，每列宽度均匀分布 */
.waterfall-column {
  width: calc((100% - 12px * (var(--column-count) - 1)) / var(--column-count));
  margin-right: 12px;  /* 列之间的右侧间距 */
}

/* 移除最后一列的右侧间距，确保布局紧凑完整 */
.waterfall-column:last-child {
  margin-right: 0;
}

/* 帖子卡片 */
.post-card {
  background-color: white;
  border-radius: 12px;
  padding: 12px;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);
  margin-bottom: 12px;
  display: flex;
  flex-direction: column;
}

/* 用户信息 */
.user-info {
  display: flex;
  align-items: center;
  margin-bottom: 8px;
}

.avatar {
  width: 25px;
  height: 25px;
  border-radius: 50%;
  margin-right: 8px;
  object-fit: cover;
}

.username {
  font-size: 13px;
  font-weight: 500;
  color: #333;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 100px;
}

/* 帖子内容 */
.post-content {
  flex: 1;
  margin-bottom: 8px;
}

/* 有图片帖子的标题样式 */
.post-title {
  font-size: 17px;
  font-weight: bold;
  margin: 0;
  line-height: 1.4;
  color: #333;
  flex: 1;
  display: -webkit-box;
  -webkit-line-clamp: 4;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

/* 无图片帖子的标题样式 */
.post-title-only {
  font-size: 17px;
  font-weight: bold;
  margin: 0;
  line-height: 1.4;
  color: #333;
  flex: 1;
  display: -webkit-box;
  -webkit-line-clamp: 4;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

/* 帖子图片容器 */
.post-image-container {
  width: 100%;
  overflow: hidden;
  border-radius: 8px;
  background-color: #f0f0f0;
}

/* 帖子图片 - 动态高度 */
.post-image {
  width: 100%;
  object-fit: cover;
  transition: transform 0.3s ease;
}

.post-image:hover {
  transform: scale(1.05);
}

/* 帖子互动数据 */
.post-stats {
  display: flex;
  padding-top: 6px;
  border-top: 1px solid #eee;
}

.stat-item {
  display: flex;
  align-items: center;
  margin-right: 16px;
  font-size: 13px;
  color: #666;
}

.stat-item .van-icon {
  margin-right: 4px;
  font-size: 15px;
}

/* 加载更多指示器 */
.loading-indicator {
  display: flex;
  justify-content: center;
  align-items: center;
  padding: 20px;
  font-size: 14px;
  color: #666;
}

/* 响应式调整：小屏幕设备(手机)的特殊处理
   1. 在小屏幕上单列显示，优化移动端浏览体验
   2. 调整布局结构为垂直堆叠
   3. 适当调整卡片内边距和间距，适应触摸操作
   4. 确保在任何设备上都能提供良好的用户体验 */
@media screen and (max-width: 375px) {
  .waterfall-column {
    width: 100%;  /* 小屏幕上单列显示 */
  }
  
  .waterfall-layout {
    flex-direction: column;  /* 布局变为垂直方向 */
  }
  
  .post-card {
    padding: 10px;  /* 调整内边距适应触摸操作 */
    margin-bottom: 10px;  /* 调整间距 */
  }
  
  .tabs-wrapper {
    padding: 8px 10px;  /* 调整选项卡内边距 */
  }
}
</style>